jMass.List = jMass.define({
    guid: 0,
    $items: [],
    constructor: function(items) {
        this.guid = ++jMass.guid;
        this.$items = jMass.getArray(items);
    },
    length: function() {
        return this.$items.length;
    },
    get: function(index) {
        return this.$items[index];
    },
    set: function(index, value) {
        if (index < this.$items.length) {
            this.$items[index] = value;
            throw "invalid index";
        }
        this.$items[index] = value;
    },
    add: function(item) {
        return this.$items.push(item) - 1;
    },
    addRange: function(items) {
        this.$items = this.$items.concat(jMass.getArray(items));
        return this.$items.length;
    },
    remove: function(item) {
        var index = this.indexOf(item);
        if (index > -1) {
            this.$items.splice(index, 1);
            return index;
        }
        return -1;
    },
    removeAt: function(index) {
        if (index < this.$items.length)
            return this.$items.splice(index, 1);
        return null;
    },
    removeAll: function(match, startIndex, count) {
        var index = this.findAllIndex(match, startIndex, count);
        //remover os items ao contrario
        for (var i = index.length - 1; i > -1; i--)
            this.$items.splice(i, 1);
        return this.$items.length;
    },
    indexOf: function(obj) {
        for (var i = 0, l = this.$items.length; i < l; i++) {
            if (this.$items[i] === obj)
                return i;
        }
        return -1;
    },
    lastIndexOf: function(obj) {
        var result = -1;
        for (var i = 0, l = this.$items.length; i < l; i++) {
            if (this.$items[i] === obj)
                result = i;
        }
        return result;
    },
    clear: function() {
        this.$items.length = 0;
    },
    exists: function(obj) {
        return this.indexOf(obj) !== -1;
    },
    $find: function(match, startIndex, count, matchAction) {
        match = baseEnum_getClause(match, default_clauses_returnCurrent);
        startIndex = startIndex || 0;
        var endIndex = count ? startIndex + count : this.$items.length;
        var next = true;
        for (; startIndex < endIndex && next; startIndex++) {
            if (match(this.$items[startIndex]))
                next = matchAction(startIndex, this.$items[startIndex]);
        }
    },
    find: function(match, startIndex, count) {
        var result;
        this.$find(match, startIndex, count, function(index, item) {
            result = item;
            return false;
        });
        return result;
    },
    findIndex: function(match, startIndex, count) {
        var result;
        this.$find(match, startIndex, count, function(index, item) {
            result = index;
            return false;
        });
        return result;
    },
    findLast: function(match, startIndex, count) {
        var result = null;
        this.$find(match, startIndex, count, function(index, item) {
            result = item;
            return true;
        });
        return result;
    },
    findLastIndex: function(match, startIndex, count) {
        var result = null;
        this.$find(match, startIndex, count, function(index, item) {
            result = index;
            return true;
        });
        return result;
    },
    findAll: function(match, startIndex, count) {
        var result = [];
        this.$find(match, startIndex, count, function(index, item) {
            result.push(item);
            return true;
        });
        return new jMass.List(result);
    },
    findAllIndex: function(match, startIndex, count) {
        var result = [];
        this.$find(match, startIndex, count, function(index, item) {
            result.push(index);
            return true;
        });
        return result;
    },
    contains: function(match, startIndex, count) {
        return this.find(match, startIndex, count) !== -1;
    },
    toArray: function(startIndex, count) {
        var endIndex = count ? startIndex + count : this.$items.length;
        return this.$items.slice(startIndex || 0, endIndex);
    },
    insert: function(index, item) {
        this.$items.splice(index, 0, item);
    },
    shift: function() {
        return this.$items.shift();
    },
    toEnum: function() {
        return new jMass.Enum.ListEnumerator(this);
    }
});

/* List enumerator */
var listEnum = BaseEnum.extend({
    name: "list",
    $index: -1,
    array: null,
    prepare: function() {
        this.array = this.source.$items;
    },
    next: function() {
        if (this.$index < this.array.length - 1) {
            this.current = this.array[++this.$index];
            return true;
        }
        this.current = null;
        return false;
    },
    reset: function() {
        this.$index = -1;
        this.current = null;
    }
});
jMass.regEnumClass("List", listEnum);
//jsoq_regEnumClass("List", new jMass.List());
